#define MSFIFO_C
#include <sys/types.h>
#include <sys/stat.h>		//mkdir()
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libmslog/mslog.h>
#include "mstime.h"
#include "mscommon.h"
#include "msfifo.h"

#define FLAG "FIFO_STRU"
#define av_assert2(cond) ((ms_void)0)
/*
块缓冲：一开始开辟一块足够大的内存，然后进行数据的存入和读取，当然也支持“长度+数据”的模式。适用于一进一出的场景
*/
static ms_s08 msfifo_innerapi_blockDrainIn(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, int ms_in  size)
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	pmsfifoblock_ctt->ptr_in += size;
	if (pmsfifoblock_ctt->ptr_in >= pmsfifoblock_ctt->ptr_end){
		pmsfifoblock_ctt->ptr_in = pmsfifoblock_ctt->ptr_begain;
	}
	pmsfifoblock_ctt->num_in+= size;
	return 0;
}

static ms_s08 msfifo_innerapi_blockDrainOut(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, int ms_in  size)
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	pmsfifoblock_ctt->ptr_out += size;
	if (pmsfifoblock_ctt->ptr_out>= pmsfifoblock_ctt->ptr_end){
		pmsfifoblock_ctt->ptr_out -= pmsfifoblock_ctt->ptr_end -pmsfifoblock_ctt->ptr_begain;
	}
	pmsfifoblock_ctt->num_out += size;
	return 0;
}

static ms_bool msfifo_innerapi_blockReset(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt)
{
	if(ms_null!=pmsfifoblock_ctt){
		pmsfifoblock_ctt->ptr_in = pmsfifoblock_ctt->ptr_out = pmsfifoblock_ctt->ptr_begain;
		pmsfifoblock_ctt->num_in = pmsfifoblock_ctt->num_out = 0;
	}
	return (ms_null!=pmsfifoblock_ctt) ? ms_true : ms_false;
}

static ms_u32 msfifo_innerapi_blockSpaceTotal(const MSFIFOBLOCKContext *pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	return (ms_u32)(pmsfifoblock_ctt->ptr_end - pmsfifoblock_ctt->ptr_begain);
}
static ms_u32 msfifo_innerapi_blockSpaceUsed(const MSFIFOBLOCKContext * ms_in pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	ms_u32 space_used=0;
	if(pmsfifoblock_ctt->num_in >pmsfifoblock_ctt->num_out){
		space_used=pmsfifoblock_ctt->num_in - pmsfifoblock_ctt->num_out;
	}else{
		space_used=(ms_u32) (0- pmsfifoblock_ctt->num_out) + pmsfifoblock_ctt->num_in;
	}
	return space_used;
}

static ms_u32 msfifo_innerapi_blockSpaceFree(const MSFIFOBLOCKContext * ms_in pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	return (ms_u32)(msfifo_innerapi_blockSpaceTotal(pmsfifoblock_ctt)- msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt));
}
static ms_s32 msfifo_innerapi_blockIOin(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, 
	ms_s32 ms_in size,ms_s32  ms_in (*func)(ms_pvoid, ms_pvoid, ms_u32))
{
	ms_s32 total= size;
	do {
		//取剩余空间和数据大小的最小值，避免踩内存
		ms_u32 len = ms_min((pmsfifoblock_ctt->ptr_end - pmsfifoblock_ctt->ptr_in), size);
		if (func) {
			len = func(pbuf, pmsfifoblock_ctt->ptr_in, len);
			if (len <= 0){
				ms_waring("%s:recv-func error",pmsfifoblock_ctt->name);
				break;
			}
		} else {
			memcpy(pmsfifoblock_ctt->ptr_in, pbuf, len);
			pbuf = (uint8_t *)pbuf + len;
		}
		//更新内部数据信息
		msfifo_innerapi_blockDrainIn(pmsfifoblock_ctt, len);
		size -= len;
	} while (size > 0);
	//更新空间使用信息
	pmsfifoblock_ctt->size_left=msfifo_innerapi_blockSpaceFree(pmsfifoblock_ctt);
	pmsfifoblock_ctt->size_used=msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt);
	//没有按预期长度存入
	if(size > 0){
		ms_waring("%s:maybe has an error,need in %d,but %d",pmsfifoblock_ctt->name,total,(total - size ));
	}
	
	//返回未存入数据的大小
	return (total - size );
}
ms_s32 msfifo_innerapi_blockIOout(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, 
	ms_s32 ms_in size,ms_s32  ms_in (*func)(ms_pvoid, ms_pvoid, ms_u32))
{
	ms_s32 total= size;
	do {
		//取剩余空间和数据大小的最小值，避免踩内存
		ms_u32 len = ms_min(pmsfifoblock_ctt->ptr_end- pmsfifoblock_ctt->ptr_out, size);
		if (func){
			len=func(pbuf, pmsfifoblock_ctt->ptr_out, len);
			if (len <= 0){
				ms_waring("%s:send-func error",pmsfifoblock_ctt->name);
				break;
			}
		}else {
			ms_memcpy(pbuf, pmsfifoblock_ctt->ptr_out, len);
			pbuf = (uint8_t *)pbuf + len;
		}
		//更新内部数据信息
		msfifo_innerapi_blockDrainOut(pmsfifoblock_ctt, len);
		size -= len;
	} while (size > 0);
	//更新空间使用信息
	pmsfifoblock_ctt->size_left=msfifo_innerapi_blockSpaceFree(pmsfifoblock_ctt);
	pmsfifoblock_ctt->size_used=msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt);

	//没有按预期长度读取
	if(size > 0){
		ms_waring("%s:maybe has an error,need out %d,but %d",pmsfifoblock_ctt->name,total,(total - size ));
	}
	//返回未读取数据的大小
	return (total - size );
}

MSFIFOBLOCKContext *msfifo_api_blockInit(ms_u32 ms_in size,ms_string ms_in name)
{
	ms_pamcheckRet(ms_null, name, "name");
//分配缓冲上下文	
	MSFIFOBLOCKContext *pmsfifoblock_ctt = ms_null;
	ms_mallocDes_goto(ms_faild, pmsfifoblock_ctt, sizeof(MSFIFOBLOCKContext), "MSFIFOBLOCKContext",name);
//开辟一大块数据存储池	
	ms_pvoid buf = ms_null;
	ms_mallocDes_goto(ms_faild, buf, size, "fifoblock_buf",name);
//初始化缓冲上下文	
	ms_strcpy(pmsfifoblock_ctt->name, name);
	pmsfifoblock_ctt->size_total=size;
	pmsfifoblock_ctt->ptr_begain = buf;
	pmsfifoblock_ctt->ptr_end=pmsfifoblock_ctt->ptr_begain + size;
	ms_byte name_mp[128]={0};
	ms_sprintfs(name_mp, "msfifo_lock_%s", name);
	mslock_api_init(&pmsfifoblock_ctt->mslock, name_mp,lockType_rw);

	msfifo_innerapi_blockReset(pmsfifoblock_ctt);

	pmsfifoblock_ctt->size_left=pmsfifoblock_ctt->size_total;
	pmsfifoblock_ctt->size_used=0;
	pmsfifoblock_ctt->num_reset=0;

	return pmsfifoblock_ctt;
ms_faild:
	ms_deMalloc(buf);
	ms_deMalloc(pmsfifoblock_ctt);
	return ms_null;
}

ms_void msfifo_api_blockDeinit(MSFIFOBLOCKContext **  ms_io ppmsfifoblock_ctt)
{
	if(ms_null!=ppmsfifoblock_ctt){
		MSFIFOBLOCKContext *pmsfifoblock_ctt=(*ppmsfifoblock_ctt);
		if(ms_null!=pmsfifoblock_ctt){
			mslock_api_deinit(&pmsfifoblock_ctt->mslock);
			ms_deMalloc(pmsfifoblock_ctt->ptr_begain);
			ms_deMalloc((*ppmsfifoblock_ctt));
		}
	}
}
ms_s32 msfifo_api_blockIn(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, 
	ms_u32 ms_in size,ms_s32  ms_in (*func)(ms_pvoid, ms_pvoid, ms_u32))
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	ms_bufcheckRetDes (-1,pbuf, "Error param ###pbuf");

mslock_api_wd(&pmsfifoblock_ctt->mslock);
	ms_s32 sizeIn=msfifo_innerapi_blockIOin(pmsfifoblock_ctt,pbuf,size, func);
mslock_api_undo(&pmsfifoblock_ctt->mslock);

	return sizeIn;
}
ms_s32 msfifo_api_blockOut(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, 
	ms_u32 ms_in size,ms_s32  ms_in (*func)(ms_pvoid, ms_pvoid, ms_u32))
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	ms_bufcheckRetDes (-1,pbuf, "Error param ###pbuf");
	// Read memory barrier needed for SMP here in theory
mslock_api_wd(&pmsfifoblock_ctt->mslock);
	ms_s32 sizeOut=msfifo_innerapi_blockIOout(pmsfifoblock_ctt, pbuf,size, func);
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	
	return sizeOut;
}
ms_s32 msfifo_api_blockLenIn(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, ms_s32 ms_in size)
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	ms_bufcheckRetDes (-1,pbuf, "Error param ###pbuf");
	if(size<0){
		ms_errRet(-1, "Error data size:%d", size);
	}
mslock_api_wd(&pmsfifoblock_ctt->mslock);
//存入数据长度
	ms_byte len_buf[4]={0};
	ms_network_4b(&len_buf[0], size);
	msfifo_innerapi_blockIOin(pmsfifoblock_ctt,&len_buf[0],4, ms_null);
//存入数据
	ms_s32 sizeIn=msfifo_innerapi_blockIOin(pmsfifoblock_ctt,pbuf,size, ms_null);
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return sizeIn;
}
ms_s32 msfifo_api_blockLenOut1(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt, ms_pvoid ms_in pbuf, ms_u32 ms_in size,ms_cstring ms_in func, ms_u32 ms_in line)
{
	ms_bufcheckRetDes (-1,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
	ms_bufcheckRetDes (-1,pbuf, "Error param ###pbuf");
	
	/*1.Read len(4 byte) from fifo*/
	ms_pbyte pbufdata=ms_null;

mslock_api_wd(&pmsfifoblock_ctt->mslock);
//读取数据长度
	ms_byte len_buf[4]={0};
	msfifo_innerapi_blockIOout(pmsfifoblock_ctt, &len_buf[0],4, ms_null);
	ms_u32 pkt_len=ms_host_4b(len_buf);
	//异常兼容，避免踩内存
	if(pkt_len>size){
		ms_bufHex("len_buf", len_buf, 4);
		mslock_api_undo(&pmsfifoblock_ctt->mslock);
		ms_errRet(-1, "%s:buf_size(%d) too small,must be large than(%d),spaceused:%d(func, line:%s,%d)",
			pmsfifoblock_ctt->name,size,pkt_len, msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt),func, line);
	}
//根据数据长度读取数据
	ms_s32 sizeOut=msfifo_innerapi_blockIOout(pmsfifoblock_ctt, pbuf,pkt_len, ms_null);
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return sizeOut;
}
ms_u32 msfifo_api_blockSizeUsed(MSFIFOBLOCKContext * ms_in pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
mslock_api_rd(&pmsfifoblock_ctt->mslock);
	ms_u32 size_used=pmsfifoblock_ctt->size_used;
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return size_used;
}

ms_u32 msfifo_api_blockSizeLeft(MSFIFOBLOCKContext * ms_in pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
mslock_api_rd(&pmsfifoblock_ctt->mslock);
	ms_u32 size_left=pmsfifoblock_ctt->size_left;
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return size_left;
}
ms_u32 msfifo_api_blockResetNum(MSFIFOBLOCKContext * ms_in pmsfifoblock_ctt)
{
	ms_bufcheckRetDes (ms_f32,pmsfifoblock_ctt, "Error param ###pmsfifoblock_ctt");
mslock_api_rd(&pmsfifoblock_ctt->mslock);
	ms_u32 num_reset=pmsfifoblock_ctt->num_reset;
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return num_reset;
}
ms_u32 msfifo_api_blockReset(MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt)
{
	//错误异常复位
	ms_u32 num_reset=0;
mslock_api_wd(&pmsfifoblock_ctt->mslock);
	if(ms_true==msfifo_innerapi_blockReset(pmsfifoblock_ctt)){
		pmsfifoblock_ctt->num_reset+=1;
		pmsfifoblock_ctt->size_left=msfifo_innerapi_blockSpaceFree(pmsfifoblock_ctt);
		pmsfifoblock_ctt->size_used=msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt);
	}
	num_reset=pmsfifoblock_ctt->num_reset;
mslock_api_undo(&pmsfifoblock_ctt->mslock);
	return num_reset;
}
ms_void msfifo_api_blockReset2(MSBFIFOSIZEContext * ms_io pmsfifsize_ctt)
{
	//彻底复位
	MSFIFOBLOCKContext * ms_io pmsfifoblock_ctt=pmsfifsize_ctt->pBFifo_ctt;
mslock_api_wd(&pmsfifoblock_ctt->mslock);
	if(ms_true==msfifo_innerapi_blockReset(pmsfifoblock_ctt)){
		pmsfifsize_ctt->num_flowoverreset=pmsfifoblock_ctt->num_reset=0;
		pmsfifsize_ctt->fifosize_left=pmsfifoblock_ctt->size_left=msfifo_innerapi_blockSpaceFree(pmsfifoblock_ctt);
		pmsfifoblock_ctt->size_used=msfifo_innerapi_blockSpaceUsed(pmsfifoblock_ctt);
		pmsfifsize_ctt->num_reset=0;
	}
mslock_api_undo(&pmsfifoblock_ctt->mslock);
}

/*
列表缓冲：按照“先入先出”的规则进行存入，注意存入的是指针而不是数据。适用于一进一出的场景
*/
MSFIFOLISTContext *msfifo_api_listMalloc(ms_u32 ms_in size,ms_string name)
{
	ms_void *buf = ms_null;
	MSFIFOLISTContext *pmsfifolist_ctt = ms_null;
	
	ms_mallocDes_goto(ms_faild,pmsfifolist_ctt, sizeof(MSFIFOLISTContext),"MSFIFOLISTContext", name);
	ms_mallocDes_goto(ms_faild,buf, size,"fifolist_buf", name);
	
	pmsfifolist_ctt->ptr= buf;
	pmsfifolist_ctt->len=size;
	pmsfifolist_ctt->next=ms_null;
	pmsfifolist_ctt->total_num=0;	//no uses
	return pmsfifolist_ctt;
ms_faild:
	ms_deMalloc(buf);
	ms_deMalloc(pmsfifolist_ctt);
	return ms_null;
}
ms_void msfifo_api_listDemalloc(MSFIFOLISTContext ** ms_io ppmsfifolist_ctt)
{
	ms_bufcheckDes (ppmsfifolist_ctt, "Error param ###ppmsfifolist_ctt");
	ms_bufcheckDes ((*ppmsfifolist_ctt), "Error param ###(*ppmsfifolist_ctt)");

	MSFIFOLISTContext *pmsfifolist_ctt=(*ppmsfifolist_ctt);
	ms_deMalloc(pmsfifolist_ctt->ptr);
	ms_deMalloc(pmsfifolist_ctt);
}
ms_void msfifo_api_listIn(MSFIFOLISTContext ** ms_io ppheader_fifolist_ctt,MSFIFOLISTContext * ms_in pmsfifolist_ctt)
{
	if(ms_null==pmsfifolist_ctt){
		return;
	}
	pmsfifolist_ctt->next=ms_null;
	if(ms_null!=ppheader_fifolist_ctt){
		//add member to list 
		MSFIFOLISTContext **p=ppheader_fifolist_ctt;
		MSFIFOLISTContext *pfifolist_ctt=(*ppheader_fifolist_ctt);
		if(pfifolist_ctt != ms_null){// already has members
			pmsfifolist_ctt->total_num=pfifolist_ctt->total_num;
			while ((*p) != ms_null){
				p = &(*p)->next;
			}
		}else{
			pmsfifolist_ctt->total_num=0;
		}
		*p = pmsfifolist_ctt;	

		//record to every member
		pfifolist_ctt=(*ppheader_fifolist_ctt);
		while (pfifolist_ctt != ms_null){
			pfifolist_ctt->total_num+=1;
			pfifolist_ctt= pfifolist_ctt->next;
		}
	}
}
MSFIFOLISTContext *msfifo_api_listOut(MSFIFOLISTContext ** ms_in ppheader_fifolist_ctt)
{
	MSFIFOLISTContext *pout_fifolist_ctt= ms_null;
	if(ppheader_fifolist_ctt != ms_null){
		MSFIFOLISTContext *pfifolist_ctt=(*ppheader_fifolist_ctt);
		//delete list member
	    	if (pfifolist_ctt != ms_null){
			MSFIFOLISTContext *pfifolist_ctt_next=pfifolist_ctt->next;
			pout_fifolist_ctt=pfifolist_ctt;
			(*ppheader_fifolist_ctt)=pfifolist_ctt_next;
		}	
		//record to every member
		pfifolist_ctt=(*ppheader_fifolist_ctt);
		while (pfifolist_ctt != ms_null){
			ms_udd(pfifolist_ctt->total_num);
			pfifolist_ctt= pfifolist_ctt->next;
		}
	}
	return  pout_fifolist_ctt;
}
ms_u32 msfifo_api_listTotalNum(MSFIFOLISTContext ** ms_in ppheader_fifolist_ctt)
{
	ms_u32 total_num=0;
	if(ppheader_fifolist_ctt != ms_null){
		MSFIFOLISTContext *pfifolist_ctt=(*ppheader_fifolist_ctt);
		if(ms_null!=pfifolist_ctt){
			total_num=pfifolist_ctt->total_num;
		}
	}
	return total_num;
}

ms_void msfifo_api_listReset(MSFIFOLISTContext ** ms_in ppheader_fifolist_ctt)
{

	ms_u32 total_num=msfifo_api_listTotalNum(ppheader_fifolist_ctt);
	while(total_num>0){
		MSFIFOLISTContext *pfifoctt=msfifo_api_listOut(ppheader_fifolist_ctt);
		msfifo_api_listDemalloc(&pfifoctt);
		total_num=msfifo_api_listTotalNum(ppheader_fifolist_ctt);
	}
}
ms_void msfifo_innerapi_shareListVarInit(MSFIFOSLISTContext *pSFifo_ctt)
{
	pSFifo_ctt->pHSList_ctt=ms_null;
	pSFifo_ctt->pTSList_ctt=ms_null;
	pSFifo_ctt->total_num=0;
}

ms_void msfifo_api_shareListInit(MSFIFOSLISTContext *pSFifo_ctt,ms_string name)
{
	msfifo_innerapi_shareListVarInit(pSFifo_ctt);
	ms_byte name_mp[1024]={0};
	ms_sprintfs(name_mp, "msfifo_lock_%s", name);
	mslock_api_init(&pSFifo_ctt->mslock, name_mp,lockType_mutex);
}
ms_void msfifo_api_shareListDeinit(MSFIFOSLISTContext *pSFifo_ctt)
{
	msfifo_api_shareListReset(pSFifo_ctt);
	mslock_api_deinit(&pSFifo_ctt->mslock);
}

/*
基于时间戳的列表缓冲：根据时间戳进行数据的读取。适用于一进多出的场景
*/

MSFIFOLISTContext *msfifo_api_shareListMalloc(ms_u32 ms_in size,ms_string name)
{
	ms_void *buf = ms_null;
	MSFIFOLISTContext *pmsfifolist_ctt = ms_null;
	
	ms_mallocDes_goto(ms_faild,pmsfifolist_ctt, sizeof(MSFIFOLISTContext), "MSFIFOLISTContext",name);
	ms_mallocDes_goto(ms_faild,buf, size, "shareList_buf", name);
	
	pmsfifolist_ctt->ptr= buf;
	pmsfifolist_ctt->len=size;
	pmsfifolist_ctt->next=ms_null;
	pmsfifolist_ctt->inTime=0;
	pmsfifolist_ctt->total_num=0;	//no uses
	return pmsfifolist_ctt;
ms_faild:
	ms_deMalloc(buf);
	ms_deMalloc(pmsfifolist_ctt);
	return ms_null;
}
ms_void msfifo_api_shareListDemalloc(MSFIFOLISTContext ** ms_io ppIdList_ctt)
{
	ms_bufcheckDes (ppIdList_ctt, "Error param ###ppIdList_ctt");
	ms_bufcheckDes ((*ppIdList_ctt), "Error param ###(*ppIdList_ctt)");

	MSFIFOLISTContext *pmsfifolist_ctt=(*ppIdList_ctt);
	ms_deMalloc(pmsfifolist_ctt->ptr);
	ms_deMalloc(pmsfifolist_ctt);
}

ms_void msfifo_api_shareListDropTimeout(MSFIFOSLISTContext *pSFifo_ctt)
{
	MSFIFOLISTContext *pHidList_ctt=pSFifo_ctt->pHSList_ctt;
	while (pHidList_ctt != ms_null){
		ms_u64 time_cha=mstime_api_us()-pHidList_ctt->inTime;
		if(time_cha>=ms_usseconds(pSFifo_ctt->timeout_drop)){
			MSFIFOLISTContext *pfifolist_ctt_next=pHidList_ctt->next;
			msfifo_api_shareListDemalloc(&pHidList_ctt);
			pHidList_ctt=pSFifo_ctt->pHSList_ctt=pfifolist_ctt_next;
			pSFifo_ctt->total_num-=1;
			if(0==pSFifo_ctt->total_num){
				msfifo_innerapi_shareListVarInit(pSFifo_ctt);
			}
		}else{
			break;
		}
	}	
}
ms_void msfifo_api_shareListIn(MSFIFOSLISTContext *pSFifo_ctt,MSFIFOLISTContext * ms_in pIdList_ctt_in)
{
//初始化成员
	if(ms_null==pIdList_ctt_in){
		return;
	}
	pIdList_ctt_in->next=ms_null;
	pIdList_ctt_in->inTime=mstime_api_us();
//添加成员到队列尾部
mslock_api_do(&pSFifo_ctt->mslock);
	if(ms_null!=pSFifo_ctt->pTSList_ctt){
		pSFifo_ctt->pTSList_ctt->next=pIdList_ctt_in;
	}else{
		pSFifo_ctt->pHSList_ctt=pSFifo_ctt->pTSList_ctt=pIdList_ctt_in;
	}
	pSFifo_ctt->total_num+=1;
//更新尾部指针
	pSFifo_ctt->pTSList_ctt=pIdList_ctt_in;
	pSFifo_ctt->inTime_last=pIdList_ctt_in->inTime;
//定时扫描，丢掉超时成员
	if(mstime_api_counterAsyncUs(&pSFifo_ctt->timebase_drop, ms_usseconds(1))){
		msfifo_api_shareListDropTimeout(pSFifo_ctt);
	}
mslock_api_undo(&pSFifo_ctt->mslock);
}
MSFIFOLISTContext *msfifo_api_shareListRead(MSFIFOSLISTContext *pSFifo_ctt,ms_u64 lastReadTime)
{
	MSFIFOLISTContext *pIdList_ctt_last= ms_null;
	MSFIFOLISTContext *pIdList_ctt=pSFifo_ctt->pHSList_ctt;
/*根据时间来获取最新的成员的地址，后续客户端自己进行链表读取和维护。
	无锁安全读取数据：建议客户端超过设置的丢包时间（timebase_drop）的2/3就进行丢包，重新获取最新的成员的地址。
	优点：可以有效避免和内部超时丢包进行临界的资源竞争，从而提升整体的IO性能*/	
	while (pIdList_ctt != ms_null){
		if(pIdList_ctt->inTime>=lastReadTime){
			return pIdList_ctt;
		}
		pIdList_ctt_last=pIdList_ctt;
		pIdList_ctt= pIdList_ctt->next;
	}
	//如果找不到，就找最近的一个
	return pIdList_ctt_last;
}
ms_u32 msfifo_api_shareListTotalNum(MSFIFOSLISTContext *pSFifo_ctt)
{
	return pSFifo_ctt->total_num;
}

ms_void msfifo_api_shareListReset(MSFIFOSLISTContext *pSFifo_ctt)
{
mslock_api_do(&pSFifo_ctt->mslock);
	MSFIFOLISTContext *pHidList_ctt=pSFifo_ctt->pHSList_ctt;
	while (pHidList_ctt != ms_null){
		MSFIFOLISTContext *pfifolist_ctt_next=pHidList_ctt->next;
		msfifo_api_shareListDemalloc(&pHidList_ctt);
		pHidList_ctt=pfifolist_ctt_next;
	}
	msfifo_innerapi_shareListVarInit(pSFifo_ctt);
mslock_api_undo(&pSFifo_ctt->mslock);
}
#undef MSFIFO_C

